# -*- coding: utf-8 -*-
from tools.linq import linq
from webapp.config import Config
import tools.download as dl
from tools.httpdoer import Request
import tools.convert as convert
import tools.zipfiletool as zipfiletool
import csv
import os
import time
import copy
from  core.sqlite3db.SqliteInner import SqliteInner
from  core.sqlite3db.SqliteSql import SqliteSql
import webview
import tools.file_operation  as fileop
import tools.globalvar as globalvar
from time import sleep

class DataUpdate:
    def set_percent(self,p):
        #self,message,percent,local_path,nposbase_path,is_full,file_ver
        percent=str(p.percent)
        message='正在下载数据...已下载 %.2f%%' % p.percent
        webview.evaluate_js(
            """
            vm.common.LoginStateChange({
              show:true,
              message: '%s'
            })
            """
            % message
        )
        if p.get_exception():
            webview.evaluate_js(
                """
                vm.common.LoginStateChange({
                  show:true,
                  message: '下载数据错误，请联系管理员'
                })
            """
            )
            sleep(3)
            webview.evaluate_js(
                """
                vm.common.LoginStateChange({
                  show:false,
                  message: ''
                })
            """
            )
        else:
            if percent=="100":
                print("下载完成")
                # 解压文件
                flag = zipfiletool.ZipFile.unzip_file(p.data["local_path"], p.data["nposbase_path"])
                if flag:
                    flag=self.update_data(p.data["is_full"], p.data["nposbase_path"])
                    if flag:
                        #更新版本号
                        fileop.setMasterObjectByKey(p.data["file_ver"],"DATAVER")
                        webview.evaluate_js(
                            """
                            vm.common.login({
                            })
                            """
                        )
                        res = {}
                        res["code"] = 0
                        res["message"] = "初始化完成"
                        return res
                    else:
                        webview.evaluate_js(
                            """
                            vm.common.LoginStateChange({
                              show:true,
                              message: '下载正确，更新数据错误，请联系管理员'
                            })
                        """
                        )
                        sleep(3)
                        webview.evaluate_js(
                            """
                            vm.common.LoginStateChange({
                              show:false,
                              message: '下载正确，更新数据错误，请联系管理员'
                            })
                        """
                        )
                else:
                    webview.evaluate_js(
                        """
                        vm.common.LoginStateChange({
                          show:true,
                          message: '下载正确，解压包错误，请联系管理员'
                        })
                    """
                    )
                    sleep(3)
                    webview.evaluate_js(
                        """
                        vm.common.LoginStateChange({
                          show:false,
                          message: ''
                        })
                    """
                    )
            #print(message)

    def Upgrade(self):
        '''
        数据更新的总入口方法
        :return:
        '''
        dataroot_path = Config.DATAROOT_PATH
        nposbase_path = dataroot_path + os.sep + "temp" + os.sep + "UPDATA"
        if not os.path.isdir(nposbase_path):
            os.makedirs(nposbase_path)


        #删除临时文件夹里所有文件
        for file in os.listdir(nposbase_path):
            c_path = os.path.join(nposbase_path, file)
            if not os.path.isdir(c_path):
                os.remove(c_path)


        res={}
        undonelist=dl.undone_list()
        if len(undonelist)>0:
            for i in range(len(undonelist)):
                task = undonelist[i].task
                dl.resume(task.id, lambda p:self.set_percent)

        else:
            #获取需要下载的文件列表服务端请求
            data_ver=globalvar.get_valuebykey("DATAVER","0") #Config.DATA_VER
            rdcecode=Config.DISTRIB_CODE
            request = Request("http://120.55.151.10:8080/api/pos/GetUpdatePosPackage")
            request.method = "post"  # 调用 _set_method
            #request.timeout = 1.99  # 调用 _set_timeout
            request.path_params = None
            request.body = {"param": convert.to_json_string(
                {"rdc_ecode": rdcecode,"ver":data_ver})}
            r = request.send(json=False)
            if r.status_code == 200:
                if r.json:
                    res = r.json
                    r_data = res["data"]
                    if r_data:
                        download_list=r_data["files"]
                        is_full=bool(r_data["is_full"])
                        download_list=linq(download_list).where(lambda x:x.url is not None and len(x.url) > 0).tolist()
                if  len(download_list) > 0:
                    #需要下载
                    self.download_file(download_list,nposbase_path,is_full)
                else:
                    #没有需要下载的数据
                    webview.evaluate_js(
                        """
                        vm.common.login({
                        })
                        """
                    )
                    res = {}
                    res["code"] = 0
                    res["message"] = "初始化完成"
                    return res
            else:
                res = {}
                res["code"] = -1
                # if r.json:
                #     mes=convert.to_dict(r.json)["message"]
                # else:
                mes="下载数据错误，如继续使用将会使用历史数据……"
                res["message"] = mes
                webview.evaluate_js(
                    """
                    vm.common.LoginStateChange({
                      show:true,
                      message: '下载数据错误，如继续使用将会使用历史数据'
                    })
                """
                )

                #之后会根据参数来判断是否需要直接到零售界面
                webview.evaluate_js(
                    """
                    vm.common.login({
                    })
                    """
                )
                return res


    def download_file(self,download_list,nposbase_path,is_full):
        '''
        下载文件并解压并更新本地库文件
        :param download_list: 需要下载的文件列表
        :param is_full: 是下载全包还是增量包
        :return:
        '''

        #download_list = []  # 需要下载的文件列表
        #is_full = False  # 是否全包
        file_url = ""  # 下载文件地址
        file_md5 = ""  # 下载文件的md5
        file_ver = ""  # 下载文件的版本号
        file_name=""#下载文件的文件名
        # if is_full:
        #     #下载全量包
        #     nposbase_path=dataroot_path+os.sep+"temp"+os.sep+"ALL"
        # else:
        #     #下载增量包


        for i in range(len(download_list)):
            file_url = download_list[i]["url"]
            file_name=str(file_url).split('/')[-1]
            file_md5 = download_list[i]["md5"]
            file_ver = download_list[i]["ver"]
            task = dl.download(file_url, nposbase_path+os.sep+file_name, self.set_percent,data={"is_full":is_full,"file_ver":file_ver,"local_path":nposbase_path+os.sep+file_name,"nposbase_path":nposbase_path})

            # while not task.done:
            #     time.sleep(1)
            #
            # while task.done:
            #     print("下载完成")
            #     #解压文件
            #     flag=zipfiletool.ZipFile.unzip_file(nposbase_path+os.sep+file_name,nposbase_path)
            #     if flag:
            #         self.update_data(is_full,nposbase_path)
            #     task.done=False

    def update_data(self,is_full,nposbase_path):
        '''
        对本地库进行更新操作
        :param is_full: 是否全包
        :return:
        '''
        #增量包读取csv文件，进行sqlite库表操作
        try:
            update_infos={}
            #当前路径下所有文件
            for file in os.listdir(nposbase_path):
                table_name=os.path.splitext(file)[0]
                if not is_full:
                    #增量包更新
                    if os.path.splitext(file)[1] == '.csv':
                        con = SqliteInner()
                        sqlitedb=con.setConnetion(Config.POSBASEDB_NAME)
                        csv_info=[]
                        with open(nposbase_path+os.sep+file, encoding='utf-8-sig') as f:
                            f_csv = csv.DictReader(f)
                            for row in f_csv:
                                csv_info.append(row)
                        for k,v in dict(csv_info[-1]).items():
                            if v !=None and v !=''and v !='rows':
                                if int(v)!=len(csv_info)-1:
                                    continue
                        update_infos[table_name]=csv_info
                        if update_infos:
                            #更新数据库操作
                            lastcreattime=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                            for k,v in (update_infos).items():
                                tablename=k
                                tableinfo=v
                                for i in range(len(v)-1):
                                    row=v[i]
                                    _id=-1
                                    _types=0
                                    _clumns=[]
                                    _values=[]
                                    for row_k,row_v in dict(row).items():
                                        if str(row_k).upper()=="ID":
                                            _id=row_v
                                        elif row_k=="@":
                                            _type=int(row_v)
                                        if row_k!="@":
                                            _clumns.append(row_k)
                                            _values.append(row_v)
                                    #sqlite3worker没法多语句一起执行
                                    #sqlitedb.execute("delete from "+tablename+" where id ="+_id)
                                    if _type==0:
                                        #sqlitedb.execute("insert into  " + tablename + str(tuple(_clumns))+" values "+str(tuple(_values)))
                                        sqlitedb.execute(SqliteSql.deleteTableRow % (tablename,_id) )
                                    else:
                                        #先查询出原表格里数据的修改时间
                                        sql=SqliteSql.getTableModifiedDate % (tablename,_id)
                                        res_tb=sqlitedb.execute(sql)
                                        if res_tb:
                                            m_date=time.strptime(str(res_tb[0][0]),'%Y-%m-%d %H:%M:%S')
                                            sql="update "+tablename+" set  "
                                            if_update=True
                                            for i in range(len(_clumns)):
                                                if str(_clumns[i]).upper()=="MODIFIEDDATE":
                                                    up_date=time.strptime(str(_values[i]),'%Y-%m-%d %H:%M:%S')
                                                    if time.mktime(m_date)>time.mktime(up_date):
                                                        if_update=False
                                                        break
                                                if i==0:
                                                    sql=sql+_clumns[i]+"='"+_values[i]+"' "
                                                else:
                                                    sql = sql + "," + _clumns[i] + "='" + _values[i] + "' "
                                            sql=sql+" where id="+_id
                                            if if_update:
                                                sqlitedb.execute(sql)

                        os.remove(nposbase_path+os.sep+file)
                        con.closedb()
                else:
                    #全包更新
                    if os.path.splitext(file)[1] == '.db':
                        sourcepath=nposbase_path+os.sep+file
                        targetpath=Config.DATAROOT_PATH+os.sep+"db"
                        if not os.path.isdir(targetpath):
                            os.makedirs(targetpath)
                        if Config.NOW_SYS=="Windows":
                            os.popen('copy '+sourcepath+" "+targetpath+os.sep+file)
                        else:
                            os.popen('cp ' + sourcepath + " " + targetpath + os.sep + file)
                        #os.remove(sourcepath)
            return True
        except Exception as e:
            return False





if __name__=='__main__':
    # csv_file = csv.DictReader(open('mytest1.csv',encoding='utf-8-sig'))
    # print(csv_file)
    # print(list(csv_file))
    #DataUpdate.update_data(DataUpdate,True,'E:\\Work\\FCPOS--R3\\poscloud\\tools\\temp\\ALL')
    # with open('mytest1.csv', encoding='utf-8-sig') as f:
    #     f_csv = csv.DictReader(f)
    #     for row in f_csv:
    #         print(row)
    dd=DataUpdate()
    dd.Upgrade()










